---@class WenheYanbing.GameLogic : Base.GameLogic
---@field public room WenheYanbing.Room
local GameLogic = Fk.Base.GameLogic:subclass("WenheYanbing.GameLogic")

function GameLogic:run()
    self:adjustSeats()
    self:assignKingdoms()
    self:gameLoop()
end

-- 分配势力
function GameLogic:assignKingdoms()
    local kingdoms = {"wei", "shu", "wu", "qun"}
    for i, player in ipairs(self.room.players) do
        player.kingdom = kingdoms[(i - 1) % #kingdoms + 1]
    end
end

-- 主游戏循环
function GameLogic:gameLoop()
    while not self:isGameOver() do
        self:startRecruitPhase()
        self:startCombatPhase()
        self:endTurn()
    end
    
    -- 游戏结束，宣布胜利者
    local winners = self:getWinners()
    if #winners > 0 then
        self.room:gameOver(winners)
    else
        self.room:gameOver({})
    end
end

-- 检查游戏是否结束
function GameLogic:isGameOver()
    local aliveCount = 0
    for _, player in ipairs(self.room.players) do
        if player.health > 0 then
            aliveCount = aliveCount + 1
        end
    end
    return aliveCount <= 1
end

-- 获取游戏胜利者
function GameLogic:getWinners()
    local winners = {}
    for _, player in ipairs(self.room.players) do
        if player.health > 0 then
            table.insert(winners, player)
        end
    end
    return winners
end

-- 招募阶段
function GameLogic:startRecruitPhase()
    self.room:setPhase("recruit")
    
    -- 使用广播通知所有玩家
    self.room:doBroadcastNotify("RecruitPhase", {
        turn = self.room.turn,
        phase = "recruit"
    })
    
    -- 给存活玩家金币并刷新酒馆
    for _, player in ipairs(self.room.players) do
        if player.health > 0 then
            player.gold = player.gold + 3
            player:refreshTavern()
            
            -- 使用简单的通知方式
            if player.doNotify then
                player:doNotify("EnterRecruit", {
                    tavernMinions = self:serializeMinions(player.tavernMinions),
                    gold = player.gold,
                    hand = self:serializeMinions(player.hand),
                    board = self:serializeMinions(player.board),
                    tavernTier = player.tavernTier,
                    upgradeCost = player:getUpgradeCost(),
                    freezeTavern = player.freezeTavern
                })
            end
        end
    end
    
    -- 设置招募阶段超时
    self.room:delay(self.room.roundTime)
end

-- 战斗阶段
function GameLogic:startCombatPhase()
    self.room:setPhase("combat")
    
    -- 使用广播通知所有玩家
    self.room:doBroadcastNotify("CombatPhase", {
        turn = self.room.turn,
        phase = "combat"
    })
    
    -- 匹配对手并进行战斗
    self:matchPlayersAndFight()
    
    -- 战斗阶段较短
    self.room:delay(20)
end

-- 匹配玩家并进行战斗
function GameLogic:matchPlayersAndFight()
    -- 简化的战斗逻辑
    local alivePlayers = {}
    
    for _, player in ipairs(self.room.players) do
        if player.health > 0 then
            table.insert(alivePlayers, player)
        end
    end
    
    -- 安全检查：如果没有存活玩家，直接返回
    if #alivePlayers == 0 then
        return
    end
    
    -- 使用自定义的洗牌函数，避免 table.shuffle 可能返回 nil
    local players = self:shufflePlayers(alivePlayers)
    
    -- 再次安全检查
    if not players or #players == 0 then
        return
    end
    
    for i = 1, #players, 2 do
        if players[i+1] then
            -- 简化的战斗：计算双方阵容强度
            local player1Strength = self:calculateBoardStrength(players[i].board)
            local player2Strength = self:calculateBoardStrength(players[i+1].board)
            
            local damage1 = math.max(1, math.floor(player1Strength / 2))
            local damage2 = math.max(1, math.floor(player2Strength / 2))
            
            -- 应用伤害
            players[i+1].health = players[i+1].health - damage1
            players[i].health = players[i].health - damage2
            
            -- 发送战斗结果 - 使用玩家自己的doNotify方法
            if players[i].doNotify then
                players[i]:doNotify("CombatResult", {
                    log = {"战斗开始", "你的阵容造成 " .. damage1 .. " 点伤害", "对手阵容造成 " .. damage2 .. " 点伤害"},
                    damageTaken = damage2,
                    opponent = {
                        id = players[i+1].id,
                        name = players[i+1].name,
                        kingdom = players[i+1].kingdom,
                        health = players[i+1].health
                    }
                })
            end
            
            if players[i+1].doNotify then
                players[i+1]:doNotify("CombatResult", {
                    log = {"战斗开始", "你的阵容造成 " .. damage2 .. " 点伤害", "对手阵容造成 " .. damage1 .. " 点伤害"},
                    damageTaken = damage1,
                    opponent = {
                        id = players[i].id,
                        name = players[i].name,
                        kingdom = players[i].kingdom,
                        health = players[i].health
                    }
                })
            end
            
            -- 检查玩家是否被淘汰
            if players[i].health <= 0 then
                self.room:doBroadcastNotify("PlayerEliminated", {
                    playerName = players[i].name
                })
            end
            if players[i+1].health <= 0 then
                self.room:doBroadcastNotify("PlayerEliminated", {
                    playerName = players[i+1].name
                })
            end
        else
            -- 奇数玩家数量时的处理
            players[i].health = players[i].health - 2
            if players[i].doNotify then
                players[i]:doNotify("CombatResult", {
                    log = {"轮空回合", "你受到 2 点伤害"},
                    damageTaken = 2
                })
            end
        end
    end
end

-- 自定义洗牌函数
function GameLogic:shufflePlayers(players)
    if not players or #players == 0 then
        return {}
    end
    
    local shuffled = {}
    
    -- 复制数组
    for i = 1, #players do
        shuffled[i] = players[i]
    end
    
    -- Fisher-Yates 洗牌算法
    for i = #shuffled, 2, -1 do
        local j = math.random(i)
        shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
    end
    
    return shuffled
end

-- 序列化随从数据
function GameLogic:serializeMinions(minions)
    local result = {}
    for _, minion in ipairs(minions) do
        if type(minion) == "table" then
            table.insert(result, {
                id = minion.id,
                name = minion.name,
                tier = minion.tier,
                attack = minion.attack,
                health = minion.health,
                kingdom = minion.kingdom,
                skills = minion.skills,
                cost = minion.cost,
                isGolden = minion.isGolden or false,
                hasTaunt = minion.hasTaunt or false
            })
        end
    end
    return result
end

-- 计算阵容强度
function GameLogic:calculateBoardStrength(board)
    local strength = 0
    for _, minion in ipairs(board) do
        strength = strength + minion.attack + minion.health + minion.tier
    end
    return strength
end

-- 结束回合
function GameLogic:endTurn()
    self.room.turn = self.room.turn + 1
end

return GameLogic